/**
 * Created by no1 on 2015/7/24.
 */
'use strict';
let DD = require('./daoLoader');
let F = require('../function');
var Base = require('./Base');
var util = require("util");

let wareDao = new DD.mongoDB.WareDao();
// 测试数据,为了后面list接口的排序
function randomInt(low, high) {
  return Math.floor(Math.random() * (high - low) + (low || 1));
}

function WareDispatcher(data) {
  data = data || {};
  data.dao = data.dao || wareDao;
  data.esDao = data.esDao || {};
  data.redisDao = data.redisDao || {};
  data.modelName = data.modelName || 'ware';
  data.modelType = data.modelType || 'mongo';
  Base.call(this, data);
}
util.inherits(WareDispatcher, Base);
/**
 @todo 添加
 */
WareDispatcher.prototype.add = function*(fields) {

  let parameters = {}
    , arr = ['id', 'version', 'name', 'vendorid', 'price', 'marketPrice', 'totalQuantity', 'images', 'discount', 'reservation', 'onLineTime', 'offLineTtime', 'graphicDetails', 'status', 'isSell']
    , retData, wareVersion
    , wareVersionid = fields.wareVersionid

  if (!wareVersionid) return F.returnData(1, '必须有wareVersionid');
  let retWareVersion = yield F.getDataFromDispatcher('wareVersionDispatcher', 'findByDis', {id: wareVersionid});
  if (retWareVersion.error == 1) return F.returnData(1, retWareVersion.msg);
  wareVersion = retWareVersion.data[0] || {};
  if (wareVersion.newest != 1) return F.returnData(1, '该wareVersion不是最新的版本');
  if (wareVersion.isSell != 1) return F.returnData(1, '该wareVersion还没有在线销售');
  //后台上架时添加在线项目
  if (fields.act == 1) {
    //获取数据
    for (let one of arr) {
      if (!fields[one]) return F.returnData(1, '必须有' + one);
      parameters[one] = fields[one];
    }
    //拼接带有loc shopInfo district 等参数的shops
    if (!!fields.shopids) {
      let shopsRet = yield F.getDataFromDispatcher('shopDispatcher', 'jointShopByids', fields.shopids, fields.vendorid);
      if (shopsRet.error == 1) return F.returnData(1, shopsRet.msg);
      parameters.shops = shopsRet.data || [];
    }
    //拼接category美容项目
    if (!!fields.cateCodes) {
      let retCate = yield F.getDataFromDispatcher('categoryDispatcher', 'jointCateByCodes', fields.cateCodes);
      if (retCate.error == 1) return F.returnData(1, retCate.msg);
      parameters.categories = retCate.data || [];
    }
    //拼接类别美容项目
    if (!!fields.serverCodes) {
      let retServices = yield F.getDataFromDispatcher('categoryDispatcher', 'jointSerByCodes', fields.serverCodes);
      if (retServices.error == 1) return F.returnData(1, retServices.msg);
      parameters.services = retServices.data;
    }
  }
  //保存数据
  let ret = yield this.dao.findAndSaveNotIncreasing({id: parameters.id}, parameters);
  if (ret.error == 1) return F.returnData(1, ret.msg);
  return F.returnData(0, ret.msg, ret.data);
};
/**
 * todo 获取最新的id
 * @returns {{error, msg, data}|{error, msg}}
 */
WareDispatcher.prototype.getNextWareId = function*(fields) {
  let id = yield this.dao.getNextSequence()
  return F.returnData(0, 'ok', {id: id});
};

WareDispatcher.prototype.synchrodata = function*(fields) {
  if (!fields.wareVersionid) return F.returnData(1, '必须有wareVersionid');
  let parameters = {}, ret = {}
    , retWV, retWare, wareVersion, wareid;
  //根据wareVersionid查询项目版本
  retWV = yield F.getDataFromDispatcher('wareVersionDispatcher', 'findByDis', {id: fields.wareVersionid});
  if (retWV.error == 1) return F.returnData(1, retWV.msg);
  wareVersion = retWV.data[0];
  //根据wareid 查询ware
  wareid = wareVersion.wareid;
  retWare = yield this.dao.getByQuery({id: wareid});
  if (retWare.error == 1) return F.returnData(1, retWare.msg);
  if (retWare.data.length > 1) return F.returnData(1, '项目有误');

  let json = JSON.parse(JSON.stringify(wareVersion));
  wareVersion = F.dataFilter(json, ['_id', '__v', '__t']);

  parameters.id = wareid;
  parameters.vendorid = wareVersion.vendorid;
  parameters.name = wareVersion.name;
  parameters.categories = wareVersion.categories;
  parameters.shops = wareVersion.shops;
  parameters.version = wareVersion.version;
  parameters.images = wareVersion.images;
  parameters.marketPrice = wareVersion.marketPrice;
  parameters.price = wareVersion.price;
  parameters.totalQuantity = wareVersion.totalQuantity || 0;
  parameters.discount = wareVersion.discount || 0;
  parameters.reservation = wareVersion.reservation || 0;
  parameters.services = wareVersion.services;
  parameters.onLineTime = wareVersion.onLineTime;
  parameters.offLineTtime = wareVersion.offLineTtime;
  parameters.updateAt = new Date();
  parameters.graphicDetails = wareVersion.graphicDetails;
  parameters.status = 1;
  parameters.isSell = 1;
  console.log(retWare.data.length);
  //添加
  if (retWare.data.length == 0) ret = yield this.dao.findAndSaveNotIncreasing({id: wareid}, parameters);
  //更新
  else if (retWare.data.length == 1) ret = yield this.dao.findAndUpdate({id: wareid}, parameters);
  if (ret.error == 1) return F.returnData(1, ret.msg);
  return F.returnData(0, 'ok', parameters);
};
/**
 * @todo 更新
 * @param fields
 * @returns {{error, msg, data}|{error, msg}}
 */
WareDispatcher.prototype.update = function*(fields) {
  if (!fields.id) return F.returnData(1, '必须有id');
  let parameters = {}, ret, retWare
    , arr = ['version', 'name', 'price', 'marketPrice', 'totalQuantity', 'images', 'discount', 'reservation', 'onLineTime', 'offLineTtime', 'graphicDetails', 'status', 'isSell']
  if (fields.act == 1) {
    for (let one of arr) if (fields[one] != null) parameters[one] = fields[one]
    //拼接带有loc shopInfo district 等参数的shops
    if (!!fields.shopids) {
      let shopsRet = yield F.getDataFromDispatcher('shopDispatcher', 'jointShopByids', fields.shopids, fields.vendorid);
      if (shopsRet.error == 1) return F.returnData(1, shopsRet.msg);
      parameters.shops = shopsRet.data || [];
    }
    //拼接category美容项目
    if (!!fields.cateCodes) {
      let retCate = yield F.getDataFromDispatcher('categoryDispatcher', 'jointCateByCodes', fields.cateCodes);
      if (retCate.error == 1) return F.returnData(1, retCate.msg);
      parameters.categories = retCate.data || [];
    }
    //拼接类别美容项目
    if (!!fields.serverCodes) {
      let retServices = yield F.getDataFromDispatcher('categoryDispatcher', 'jointSerByCodes', fields.serverCodes);
      if (retServices.error == 1) return F.returnData(1, retServices.msg);
      parameters.services = retServices.data;
    }
  }
  ret = yield this.dao.findAndUpdate({id: fields.id}, parameters);
  if (ret.error == 1) return F.returnData(1, ret.msg);
  return F.returnData(0, ret.msg, ret.data);
};

/**
 * @todo 列表
 * @param fields
 * @param fields.act 1 商品列表中的 list 2 门店详情中的list(传入sid) ,
 * @returns {{error, msg, data}|{error, msg}}
 */
WareDispatcher.prototype.list = function*(fields) {
  let retData = []
    , tmp = {}
    , page = fields.page || 1
    , pageSize = fields.pageSize || 50;
  //手机端默认列表
  if (fields.act == 1) {
    //查询条件
    let nearQue = {};
    if (fields.districtCode && fields.districtCode != 0) nearQue["shops.district.code"] = fields.districtCode;
    if (fields.cateCode) nearQue["categories.code"] = fields.cateCode;

    //页码
    fields.page = fields.page || 1;
    fields.pageSize = fields.pageSize || 50;
    let num = yield F.getMonLimit(fields.page, fields.pageSize, 1000);

    //为方法Aggregate拼接参数
    let arr = [];
    arr[0] = {
      '$geoNear': {
        'near': fields.loc || [],
        'spherical': true,
        'distanceField': 'dist',
        'includeLocs': 'loc',
        'query': nearQue,
        'num': num//一定数量内1000 2000 ...
      }
    };
    arr[1] = {$match: nearQue};//查询条件
    arr[2] = {$sort: {"eAverage": -1}};//评分排序 评价最好
    arr[3] = {$sort: {"buyNumber": -1}};//销量排序 人气最高
    arr[4] = {$skip: (fields.pageSize * (fields.page - 1))};
    arr[5] = {$limit: fields.pageSize * fields.page};

    //筛选项
    let proj = {};
    proj._id = 0;
    let arrPorAdd = ['id', 'name', 'images', 'price', 'marketPrice', 'shops', 'loc', 'status', 'buyNumber'];
    for (let one of arrPorAdd) proj[one] = 1;

    arr[6] = {$project: proj};

    let sort = fields.sort || 1;
    let pip = [];
    pip.push(arr[1]);
    if (sort == 1) {//智能推荐
      pip.push(arr[2]);
      pip.push(arr[3]);
    } else if (sort == 2) {//评价最好
      pip.push(arr[2]);
    } else if (sort == 3) {//人气最高
      pip.push(arr[3]);

    }
    pip.push(arr[4]);
    pip.push(arr[5]);
    pip.push(arr[6]);
    //获取数据
    let ret = yield this.dao.getByAggregate(pip);
    if (ret.error == 1) return F.returnData(1, ret.msg);
    tmp = ret.data;

    //返回的图片只要第一张
    for (let one of tmp) {
      if (one.images) {
        one.image = one.images[0] || '';
        delete one.images;
      }
      retData.push(one);
    }
  }
  //机构详情中的list
  else if (fields.act == 2) {//查询商家id为 X 的 商品
    let que = {};
    que['shops.sid'] = fields.sid;

    let arr = ['id', 'price', 'marketPrice', 'buyNumber', 'name', 'images'];
    let opt = {};
    opt._id = 0;
    for (let one of arr) opt[one] = 1;

    //获取数据
    let ret = yield this.dao.getByQuery(que, opt, fields.page, fields.pageSize);
    if (ret.error == 1) return F.returnData(1, ret.msg);
    tmp = ret.data;
    //返回的图片只要第一张
    for (let one of tmp) {
      if (one.images) {
        one.image = one.images[0] || '';
        delete one.images;
      }
      retData.push(one);
    }
  }
  //总后台项目列表
  else if (fields.act == 4) {
    if (!fields.vid) return F.returnData(1, '必须有vid');
    let isPaging = fields.isPaging || 0
      , retDataList
      , retCount
      , opt = {}
      , arr = ['id', 'name', 'price', 'totalQuantity', 'buyNumber', 'onLineTime', 'offLineTtime', 'status']
      , Qut = {}
    //拼接返回选项
    for (let one of arr) opt[one] = 1;
    //拼接查询条件
    Qut.vendorid = fields.vid;
    //获取列表数据
    let ret = yield this.dao.getByQueryPor(Qut, opt, {page: page, pageSize: pageSize}, {id: -1});
    if (ret.error == 1) return F.returnData(1, ret.msg);
    retDataList = ret.data;
    //获取列表总条数
    if (isPaging == 1) {
      retCount = yield this.dao.getCountByQuery(Qut);
      if (retCount.error == 1) return F.returnData(1, retCount.msg);
    }
    //拼接数据
    retData = {};
    if (isPaging == 1) {
      retData.list = retDataList;
      retData.count = retCount.data;
    } else retData = retDataList
  }

  //过滤没有字段
  let json = JSON.parse(JSON.stringify(retData));
  retData = F.dataFilter(json, ['_id', 'shopInfo']);
  return F.returnData(0, 'OK', retData);
};

/**
 * @todo listByName
 * @param fields
 * @returns {{error, msg, data}|{error, msg}}
 */
WareDispatcher.prototype.listByName = function*(fields) {
  let name = fields.name;
  //页码
  fields.page = fields.page || 1;
  fields.pageSize = fields.pageSize || 50;
  if (!name) {
    return F.returnData(1, '没有商品名');
  }
  let fun = fields.fun || 1;
  if (fun == 2) {
    let retData = {};
    //过滤无效字段
    let arr = ['_id', '__t', 'updateAt', 'ts', '__v', 'createdAt'];
    let opt = {};
    for (let one of arr) {
      opt[one] = 0;
    }
    let arrDel = ['categories', 'shops', 'notice', 'images', 'services', 'discountDetails', 'notesToBuy', 'exceptTime', 'waresLib',
      'totalQuantity', 'price', 'marketPrice', 'buyNumber', 'version', 'serviceGrade', 'decorationGrade', 'esTimate', 'eAverage'
      , 'eCount', 'eTotal', 'reservation', 'discount', 'onLineTime', 'offLineTtime', 'shortName', 'otherInfo', 'payWay', 'content', 'status', 'graphicDetails'];

    for (let two of arrDel) {
      opt[two] = 0;
    }

    //构造模糊条件
    let query = {};
    //query['name'] = '/' + name + '/';
    query['name'] = {$regex: name};
    //分页参数
    let ret = yield this.dao.getByQuery(query, opt, fields.page, fields.pageSize);
    if (ret.error == 1) {
      return F.returnData(1, ret.msg);
    }
    if (ret.data.length <= 0) {
      return F.returnData(1, '没有找到商品数据');
    }
    let data = JSON.parse(JSON.stringify(ret.data));

    data = F.dataFilter(data, ['_id']);
    retData = data;
    for (let item in retData) {
      if (retData[item]['vendorid']) {
        let vid = parseInt(retData[item]['vendorid']);
        let vname = yield F.getDataFromDispatcher("vendorDispatcher", "findOne", {
          "field": {"id": vid},
          "opts": {"name": 1, "_id": 0}
        });
        retData[item]['vendorName'] = vname.name;
      } else {
        retData[item]['vendorName'] = "";
      }
      delete  retData[item]['vendorid'];
    }
    return F.returnData(0, 'OK', retData);
  }
  if (fun == 1) {
    let pro = {};
    //需要显示的字段
    let arrAdd = ['_id', 'id', 'name', 'vendorid'];
    for (let i of arrAdd) {
      pro[i] = 1;
    }
    let arr = [];
    arr[0] = {$project: pro};
    arr[1] = {$match: {"name": {$regex: name}}};
    arr[2] = {$skip: (fields.page - 1)};
    arr[3] = {$limit: fields.pageSize};
    let ret = yield this.dao.getByAggregate(arr);
    if (ret.error == 1) {
      return F.returnData(1, ret.msg)
    }
    ;
    let data = JSON.parse(JSON.stringify(ret.data));
    data = F.dataFilter(data, ["_id"]);
    let retData = data;

    for (let item in retData) {
      if (retData[item]['vendorid']) {
        let vid = parseInt(retData[item]['vendorid']);
        let vname = yield F.getDataFromDispatcher("vendorDispatcher", "getOneByQuery", {id: vid}, {
          "name": 1,
          "_id": 0
        });
        retData[item]['vendorName'] = vname.data.name;
      } else {
        retData[item]['vendorName'] = '';
      }
      delete  retData[item]['vendorid'];
    }
    return F.returnData(0, 'OK', retData);
  }
};
/**
 * @todo 获取详情
 * @param fields
 * @returns {{error, msg, data}|{error, msg}}
 */
WareDispatcher.prototype.detail = function*(fields) {
  let ID = fields.id
  if (!ID) return F.returnData(1, '没有ID');
  let retData = {};

  //返回全部
  if (fields.act == 1) {
    let json = {};
    if (fields.loc) {
      let nearQue = {}
      nearQue.id = ID;
      let arr = [{
        '$geoNear': {
          'near': fields.loc || [],
          'spherical': true,
          'distanceField': 'dist',
          'includeLocs': 'loc',
          'query': nearQue
          //'num': num//一定数量内1000 2000 ...
        }
      }];
      let retAggre = yield this.dao.getByAggregate(arr);
      json = JSON.parse(JSON.stringify(retAggre.data[0]));
    }
    else {
      let ret = yield this.dao.getOneByQuery({id: ID});
      if (ret.error == 1) return F.returnData(1, ret.msg, 3);
      json = JSON.parse(JSON.stringify(ret.data));
    }
    retData = F.dataFilter(json, ['_id', '__v', '__t', 'sName', 'district', 'otherInfo', 'updateAt', 'createdAt', 'shopInfo', 'sPrice', 'sAmount', 'ts'], true)
  }
  //下单前的信息
  else if (fields.act == 2) {
    let opt = {};
    let arrDel = ['_id', 'categories', 'createdAt', 'otherInfo', '__v', '__t', 'shops._id', 'shops.shopInfo', 'ts', 'updateAt', 'shops.district._id', 'categories._id', 'services._id', 'discountDetails._id', 'discountDetails.item._id', 'notesToBuy._id', 'exceptTime._id']
    for (let one of arrDel) opt[one] = 0;
    let ret = yield this.dao.getOneByQuery({id: ID}, opt);
    if (ret.error == 1) return F.returnData(1, ret.msg);

    //拼接返回数据
    retData.id = ret.data.id || '';
    retData.name = ret.data.name || '';
    retData.price = ret.data.price || '';
  }
  return F.returnData(0, 'OK', retData);

};
/**
 * @todo 商品被购买一件 内部调用
 * @param fields
 * @returns {*}
 */
WareDispatcher.prototype.buyOne = function*(id) {
  let ret = yield this.dao.buyOne(id);
  return ret;
};
/**
 * @todo 商品被购买 内部调用
 * @param id
 * @param quantity
 * @returns {*}
 */
WareDispatcher.prototype.buySome = function*(id, quantity) {
  let ret = yield this.dao.buySome(id, quantity);
  return ret;
};
/**
 * todo 添加评价 内部调用
 * @param evaluation
 */
WareDispatcher.prototype.evaluate = function*(evaluation) {
  return 0
};
/**
 * 内部调用
 * @param Que
 * @returns {{error, msg, data}|{error, msg}}
 */
WareDispatcher.prototype.findByDis = function*(Que, opts) {
  opts = opts || {};
  let arrDel = ['_id', '__v', '__t', 'createdAt', 'updateAt']
    , opt = {};
  if (!!opts.arrDel) arrDel = arrDel.concat(opts.arrDel);

  for (let one of arrDel) opt[one] = 0;
  let ret = yield this.dao.getByQuery(Que, opt);
  if (ret.error == 1) F.returnData(1, ret.msg, ret.data);
  return F.returnData(0, ret.msg, ret.data);
};
module.exports = WareDispatcher;